const { Op } = require("sequelize");
const { Dict, DictItem, sequelize } = require("../../../../models");
const utils = require("../../../../utils");
module.exports = {
  // 创建/编辑字典
  async saveOrUpdate(req, res, next) {
    try {
      const { id } = req.body;
      return id
        ? this.updateDict(req, res, next)
        : this.saveDict(req, res, next);
    } catch (error) {
      next(error);
    }
  },

  // 创建字典
  async saveDict(req, res, next) {
    try {
      const user = await Dict.create(req.body);
      return user ? res.cc(null, "成功创建") : res.err("创建失败");
    } catch (error) {
      next(error);
    }
  },

  // 更新字典
  async updateDict(req, res, next) {
    try {
      const { id } = req.body;
      // 1、校验字典是否存在
      let item = await this.checkDictInfo(id, next);
      // 2、组装参数
      await utils.assignEditValue(item, req.body);
      // 3、执行更新
      const result = await item.save();
      return result ? res.cc(null, "更新成功") : res.err("更新失败");
    } catch (error) {
      next(error);
    }
  },

  // 删除字典（同时会删除字典项）
  async batchDelete(req, res, next) {
    sequelize.transaction(async (t) => {
      try {
        const { ids } = req.body;
        if (!ids || ids.length === 0) throw new Error("ids不能为空");
        const dicts = await Dict.findAll({
          where: {
            id: {
              [Op.in]: ids,
            },
          },
          include: [
            {
              model: DictItem,
              attributes: ["id"],
              as: "options",
            },
          ],
          transaction: t,
        });
        const dictItemIds = dicts.reduce((pre, curr) => {
          const itemIds = curr.dataValues.options.map((el) => el.dataValues.id);
          return pre.concat(itemIds);
        }, []);
        if (dictItemIds.length > 0) {
          await DictItem.destroy({
            where: {
              id: {
                [Op.in]: dictItemIds,
              },
            },
            transaction: t,
          });
        }
        await Dict.destroy({
          where: {
            id: {
              [Op.in]: ids,
            },
          },
          transaction: t,
        });

        return res.cc(null, "删除成功");
      } catch (error) {
        next(error);
      }
    });
  },

  //  校验字典是否存在、编辑时更改信息
  async checkDictInfo(id, next) {
    try {
      // 判断id的数据是否存在
      const dictItem = await Dict.findByPk(id);
      if (!dictItem) {
        throw new Error("字典数据不存在");
      }

      return dictItem;
    } catch (error) {
      next(error);
    }
  },

  // 获取字典列表
  async getDictList(req, res, next) {
    try {
      const params = await this.getSearchParams(req);
      const dicts = await Dict.findAll(params);
      return res.cc(dicts);
    } catch (error) {
      next(error);
    }
  },
  // 获取字典分页
  async getDictPage(req, res, next) {
    try {
      const params = await this.getSearchParams(req, "page");
      const { count, rows } = await Dict.findAndCountAll({
        ...params,
        distinct: true,
      });
      return res.page(count, rows);
    } catch (error) {
      next(error);
    }
  },
  // 组装查询参数
  async getSearchParams(req, type = "list") {
    const { dictName, dictCode, page = 1, limit = 10 } = req.body;
    const pageParams = {
      limit: parseInt(limit),
      offset: (parseInt(page) - 1) * parseInt(limit),
    };
    return {
      order: [["createTime", "ASC"]],
      attributes: {},
      ...(type === "page" ? pageParams : {}), // 查询全量数据时，不进行分页
      where: {
        dictName: {
          [Op.like]: `%${dictName ?? ""}%`,
        },
        dictCode: {
          [Op.like]: `%${dictCode ?? ""}%`,
        },
      },
      include: [
        {
          model: DictItem,
          attributes: ["id", "label", "value", "status"],
          as: "options",
          ...(type === "list" ? { where: { status: "1" } } : {}), // 全量数据时，只展示status为1的数据
        },
      ],
    };
  },
};
